fix(control-plane): withhold auxiliary polls on replan-bound turns - #5287
Conversation
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
|
This pull request has merge conflicts with Choose the remote for the base repository, not an out-of-date fork. git fetch upstream
git rebase upstream/main
# Resolve each conflict, git add the resolved files, then git rebase --continue.
git push --force-with-lease origin HEADFor a same-repository clone whose Keep the DCO |
huangruiteng
left a comment
There was a problem hiding this comment.
Approval conclusion (author-owned PR; GitHub blocks formal self-approval)
评审 head:ba04dd27d967c5f6d34b0e057f23fe690178a4f7。结论:APPROVE,未发现该 head 的阻断项。以下按 LoopX PR review capability 的当前评审契约执行;批准代码结论不等于批准合并。
动机
这个修复解决的是一条不可执行的恢复路径:Turn 已经绑定自主 replan 的结算身份,却仍向 Agent 展示辅助 monitor-poll 命令。真正执行时,原有 admission 会拒绝把同一 Turn 改绑为 Todo 观察,造成“状态说可以执行、实际执行被拒绝”的反复尝试。目标不是放宽单一结算身份,而是让 CLI 投影准确呈现这个边界。它完成了这个有用且独立的修复,不声称关闭整个长期运行路线图。
改动思路
入口仍是 quota should-run 生成的 interaction contract。原来的类型化 replan settlement owner 已经决定绑定究竟是 Todo 还是自主 replan;本 PR 读取其结果,不从 Todo 文案、任务类别或监控列表另造判断源。只在自主 replan 分支撤下两条不可执行命令,保留 monitor 上下文和“先结算、再从 Todo-bound Turn 观察”的恢复提示。已有显式未绑定与缺少 Turn ID 的拒绝优先级不变,Todo-bound replan 仍可执行辅助 poll。
正向恢复也做了真实验证:完成 replan 的 refresh-state 和 spend-slot 后,新建/认领的验证 Todo 可以成为后续 Turn 的绑定;该 Turn 执行 monitor-poll 成功。新 Turn 首次投影若要求显式绑定,就使用选中 Todo 的 ID 补充绑定;没有绕过原有授权或结算检查。
具体改动
生产文件增加 16 行,测试增加 55 行、删除 2 行;没有增加持久化状态、CLI 参数或第二个结算 owner。
关键代码讲解
_turn_scoped_cli_settlement_context(interaction_contract.py:547)取得已经验证的 replan settlement contract,并与当前 Turn 的结算计划一起返回。它是本次判断的输入来源,选中 Todo 时继续返回 Todo 绑定,而不是仅凭存在 replan obligation 就阻断。projectReplanSettlementContract(replan_settlement.ts:174,未修改)保持类型化绑定联合的所有权。Python 只消费其settlement_binding.kind;这次没有复制 TypeScript 的状态机,也没有改变 lease、claim 或额度权限。_build_interaction_cli_channel(interaction_contract.py:1265)在原有显式绑定检查、缺失 Turn ID 检查之后,新增自主 replan 的命令可用性分支。它输出 receipt_binding_required 和可操作的下一步,且同时省略普通与 material-change 命令;其他路径继续由原有 builder 输出。辅助 poll 仍是可选、不抢占主任务、no-spend,并不取消主工作义务。
测试文件覆盖自主 replan 被撤下命令、Todo-bound replan 保留命令和普通未绑定非-replan 路径的原有投影。这里的普通未绑定投影兼容性不等于真实 admission 被放宽,最终仍由 receipt admission 拒绝不合法身份。
对主干的风险
最危险的反向回归是把所有 replan 都禁掉,使合法 Todo-bound replan 的观察永久停住。本次按类型化绑定区分,不按 replan 这个词或任务文案分类。独立的 base/head 合成 fixture 通过真实 CLI 和原有 native admission 验证:基线错误显示 ready,执行得到身份冲突;head 正确显示绑定前置条件,强行执行旧命令仍被拒绝,状态字节不变、观察记录为零、花费为零。随后恢复到新的 Todo-bound Turn,poll 成功;普通 Todo-bound poll 重放仅保留一条观察,且不花额度。四组完整投影对照还保留了既有拒绝优先级和合法路径。
本地验证:7 个相关测试文件共 66 个测试通过;loopx canary premerge --from-git-diff --git-diff-base ee1ea64b0aef45fdda81d2d7e48da356a1750eab 的 5 项直接检查与 18 项选中检查通过;两个修改文件 Ruff 与 diff whitespace 检查通过。真实边界是隔离的 File/SQLite 合成状态及 native admission,不涉及活跃 Goal、真实外部监控请求或付费模型。独立恢复 fixture 的指纹为 c3a83b79e5a8e35637536979c48cea4ee8da8f4b6c8951c6cd129eb84f9e0032,base 为上述不可变提交,head 为本次评审提交。
语义与 CI 对齐
本 PR 复用已有绑定语义,显式披露“原先展示不可执行命令,现在展示结算前置条件”的默认行为变化;错误提示使用目标无关的 Turn、Todo、replan 术语,没有把强制工作义务称作建议。它不是新增 opt-in 能力,因此没有新增默认关闭门或自动安装指令。当前 Goal 的评审策略不等待远端 CI,本次未查询或轮询 CI。
最新 main 已含 #5279 的同文件 scoped-gate 修复,这与本 PR 的 replan 投影问题不是同一修复。已有合并冲突须整合后再验证新 head,不能直接继承本次批准;这属于合并就绪条件,不是该不可变 head 的代码阻断发现。
我的整体评价
long_horizon:improved,避免反复尝试不可能的辅助命令,并证明结算后仍能继续有用工作。user_experience:improved,CLI 从误导性的 ready 变为准确前置条件,恢复只补充已有权威状态所需的绑定,没有新增用户确认。代码量与问题相称,兼容路径保持原有语义;未来向前的精简检查考虑了单一绑定 owner,当前已经复用它,无需为了 16 行投影增加新抽象。残余风险是与最新 main 整合后的 exact-head 验证,以及真实外部监控自身的可用性;后者不在此修复的验收范围。本轮不合并。
English verdict: APPROVE - ba04dd2. Auxiliary commands now match the existing single-Turn receipt boundary; actual CLI refusal, settlement-to-Todo recovery and replay were verified. 66 focused tests and all selected premerge checks passed. Rebase/integration requires a fresh exact-head review; no merge or remote CI polling.
cocolord
left a comment
There was a problem hiding this comment.
动机
这个 PR 修复的是一条可复现的控制面自相矛盾:同一 Turn 的 heartbeat receipt 已经绑定到 autonomous replan,但状态变化后出现一个到期的 watch-only Monitor 时,旧版 quota should-run 仍把辅助 monitor-poll 投影为 ready;照着命令执行却必然得到 heartbeat_receipt_identity_conflict。这会让自动化反复尝试一个不可能成功的动作。目标是让投影诚实反映既有的单 Turn 单结算身份约束,而不是放宽 Monitor 写入权限。
改动思路
实现复用既有 TypeScript replan settlement owner 的类型化结果。Python 的 interaction contract 只读取 replan_settlement_contract.settlement_binding.kind:显式未绑定和缺少 Turn ID 的既有拒绝优先级保持不变;绑定种类为 autonomous_replan 时,辅助观察改为 receipt_binding_required,给出先结算当前 replan、再从 Todo-bound Turn 观察的恢复路径,并撤下普通及 material-change 两条不可执行命令。Todo-bound replan 继续走原来的 ready 分支,真实 poll、回执和零额度语义不变。
具体改动
完整 diff 只有两个文件、+71/-2,没有新持久化字段、CLI 参数、权限或第二状态权威。
关键代码讲解
_turn_scoped_cli_settlement_context继续负责把 TypeScript owner 产生的 settlement plan 与 replan settlement contract 带入 CLI 投影;它没有在 Python 重新判断 replan 状态。projectReplanSettlementContract是未修改的类型化决策 owner,依据是否有 selected Todo 生成todo或autonomous_replan的 discriminated binding。本 PR 消费这个字段,而非按 Todo 文案、标题或子串分类。_build_interaction_cli_channel在辅助 Monitor 分支读取settlement_binding。仅当 kind 为autonomous_replan时返回auxiliary_monitor_replan_receipt_binding并省略命令;Todo 绑定和普通合法 Turn 仍生成原命令。test_auxiliary_monitor_poll_availability.py增加 replan-bound 反例及 Todo-bound replan 正例,并补齐 Codex App heartbeat execution context,使断言覆盖真实命令投影形状。
对主干的风险
主要风险是条件过宽,导致任何带 replan obligation 的 Turn 都失去合法辅助观察。独立 public CLI 反事实排除了这一点:在 immutable base 上,先建立 autonomous-replan receipt、再出现 advancement Todo 与到期 Monitor 时,投影为 ready 且含两条命令,但强制执行返回 heartbeat_receipt_identity_conflict,没有写入观察;在 exact head 上,同一输入变为 receipt_binding_required,两条命令均被移除,强制旧命令仍失败关闭。另一条 Todo-bound replan 路径仍投影 ready,真实 poll 成功、只写入一条 observation,quota spend 为 0。42 个相关测试、changed-file Ruff、Python compile 和 diff whitespace 检查通过。
远端 4 个失败检查也已用同一命令在 immutable base ee1ea64b0aef45fdda81d2d7e48da356a1750eab 与 exact head 上复现:两项 registry census 都报告同一个 loopx/cli.py metadata drift,两项 settlement 测试都保持相同的 scheduler ACK 断言形状;这些路径不在本 PR diff,因此不归因于本改动。当前 head 与最新 main 存在 interaction_contract.py 内容冲突,因为 #5279 已改动同一分支。它不否定该 immutable head 的行为结论,但 rebase/整合后的新 head 必须重新跑上述反事实与 freshness review,当前批准不构成 merge-ready。
语义与 CI 对齐
改动复用现有 todo | autonomous_replan typed binding,没有 substring denylist;提示使用 Turn、Todo、replan 等通用控制面术语。行为变化已明确为“从展示必失败命令改为展示机器前置条件”,receipt_binding_required 是强制 admission 约束而不是建议。现有 required CI 仍红且 PR 仍有冲突,所以合并门禁保持关闭。
我的整体评价
APPROVE exact head ba04dd27d967c5f6d34b0e057f23fe690178a4f7。收益已经由 base/head 真实 CLI 差分验证:错误的 ready 被准确的 binding requirement 取代,非法写入继续失败关闭,Todo-bound 合法观察不被误伤且不消费额度。代码量小、职责落在现有投影边界、没有复制状态机,也没有未闭合的 exact-head 行为风险。相关的 bounded future-facing 检查认为无需再加抽象;真正剩余的是与 #5279 的整合工作,作者更新 head 后必须重新审查。此批准仅是代码评审结论,不授予合并权限。
English verdict: APPROVE ba04dd27d967c5f6d34b0e057f23fe690178a4f7. A real base/head CLI counterfactual confirms that the misleading ready command is removed only for autonomous-replan-bound Turns, while Todo-bound replan polling still succeeds with one observation and zero spend. Focused tests and static checks pass; four CI failures match the immutable base. The branch conflicts with current main, so any rebased head requires a fresh review and this approval is not merge authority.
Signed-off-by: huangruiteng <huangrt01@163.com>
Signed-off-by: huangruiteng <huangrt01@163.com>
Signed-off-by: huangruiteng <huangrt01@163.com>
…lan-receipt-20260929 Signed-off-by: huangruiteng <huangrt01@163.com>
huangruiteng
left a comment
There was a problem hiding this comment.
Approval conclusion (author-owned PR; GitHub blocks formal self-approval)
Exact reviewed head: c7ee1c28f61b22eb7544321e83da5b65fdf12d1a; integrated base: 0644abaaa95cb14573ff342830d1838065c98143.
动机
评审整个 PR 及与当前主干的组合。问题是 autonomous-replan-only Turn 给出了看似可执行的辅助 monitor 命令,但它无法绑定到当前结算身份;执行后才报 identity conflict,浪费回合且仍需操作者补位。正确结果是入口就说明缺什么绑定,并保留结算后通过 Todo-bound Turn 继续观测的真实路径。
改动思路
最小方案是让现有 interaction projection 消费已有 typed replan_settlement_contract.settlement_binding,不另建排程、配额或 receipt 决策 owner。Python 仍是展示/CLI transport,既有 TypeScript settlement 与 native quota/lease 合法性保持权威。禁止所有 replan monitor 会过度拦截,所以只针对 kind=autonomous_replan;已有选定 Todo 的重规划仍保持可执行。
具体改动
关键代码讲解
interaction_contract 在显式 receipt-binding 和缺少 turn_instance_id 两项拒绝之后、原 user-gate scope 检查之前识别 autonomous-replan binding,给出 receipt_binding_required 和恢复说明,同时不发普通/物质变化 poll 命令。整合冲突时保留主干 gate_scope 独立性约束及 target-key 参数,没有覆盖它们。availability 测试加入 replan-only 拒绝和 todo-bound replan 正例,仍验证普通合法 Turn 和显式身份拒绝优先级。
相邻 state-machine smoke 原先要求 transport 自动 trim required-read 命令,但主干的 admitted-command 契约明确要求原样运输;不可变 main/head 都复现该断言失败。本次将 oracle 修为输入命令完整镜像到 agent/CLI 两端,user 端仍不显示,而非修改生产 transport 或删掉检查。
对主干的风险
语义与 CI 对齐
风险集中于过度封锁独立 monitor、错误判定 settlement kind 和丢失主干用户 gate。当前精确范围的 25 项 availability/routing/settlement/CLI projection 回归、35 项真实 native/public-CLI/lease monitor 回归及共享 state-machine smoke 通过。相同 admitted replan-only fixture 在 main 是 ready+两条命令,在 head 是 binding-required+零命令;选定 Todo 的 replan 仍可执行。native 正负验证包含身份/租约/重试、结算后继续与零重复业务效果。没有绕过活跃 Goal、重写历史 receipt 或把有记录的 blocker 误称恢复成功。
最终 premerge 全通过,质量回执绑定当前三文件范围;无失败、必需跳过或 manual hold。早期旧 whitespace oracle 的失败保留并通过 base/head 归因后修复。公开边界及 DCO 合格;按 Goal policy 未查询或等待 CI。此处 CLI transport 变化不要求前端配置 companion,既有 App/Lark 共用同一 interaction/status 合法性;没有新开关或状态 owner。
我的整体评价
APPROVE:拒绝范围有精确 typed 依据,合法独立 monitor 和 Todo-bound replan 继续路径保留。相邻修正没有扩散到权限或排程规则。按所有者明确授权合并当前提交;该修复只闭合错误命令投影与恢复路径,不宣称全局自主协作已经验收。
No blocking finding. Residual risk: browser provider fixtures do not certify model intent quality; installed readback follows merge.
English verdict: APPROVE - exact head c7ee1c28f61b22eb7544321e83da5b65fdf12d1a; integration blockers resolved and affected native/packaged invariants plus risk-based premerge pass. Owner-authorized merge; broader adoption and installed delivery are separate readbacks.
Goal And Delivered Outcome
ready, but running its projected command failed withheartbeat_receipt_identity_conflict. The CLI now reportsreceipt_binding_required, with the valid next step, and omits the unusable command. Todo-bound Turns keep their auxiliary poll command.main. Related fix: fence scoped auxiliary Monitor admission and routing #5279 changes the same projection file for scoped User-gate admission; this PR handles the distinct autonomous-replan receipt binding case.Scope And Continuation
Validation
git diff --check, andloopx checkon both changed paths; no public-boundary findings.loopx checkreported two unrelated existing Goal-state warnings.loopx canary premerge --from-git-diffwith the managed quality gate on the exact commit: 5 direct checks and 18 selected checks passed. Initial setup-only failure (missing npm TypeScript dependency) resolved bynpm ci --ignore-scriptsbefore the successful rerun.Frontend / Visual Evidence
Type of Change
LoopX Area
Technical Direction
Shared-authority RFC fixture impact
N/A. This PR does not claim provider migration or shared authority promotion.
Boundary Checklist